package com.ctsi.ssdc.service.impl;


import com.ctsi.ssdc.repository.OrderMapper;
import com.ctsi.ssdc.util.OrderUtil;
import org.springframework.stereotype.Service;
import org.apache.commons.collections.CollectionUtils;
import com.ctsi.ssdc.domain.LitemallOrder;
import com.ctsi.ssdc.domain.LitemallOrderExample;
import com.ctsi.ssdc.service.LitemallOrderService;
import com.ctsi.ssdc.repository.LitemallOrderRepository;
import org.apache.commons.lang3.StringUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import com.ctsi.ssdc.service.impl.StrengthenBaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import com.ctsi.ssdc.model.PageResult;
import org.springframework.data.domain.Pageable;
import com.github.pagehelper.PageHelper;

import static com.ctsi.ssdc.util.CharUtil.getRandomNum;

/**
 * Service Implementation for managing LitemallOrder.
 *
 * @author ctsi-biyi-generator
 *
 */
@Service
public class LitemallOrderServiceImpl 
	extends StrengthenBaseServiceImpl<LitemallOrderRepository, LitemallOrder, Integer, LitemallOrderExample> 
	implements LitemallOrderService {

    @Autowired
    LitemallOrderRepository litemallOrderRepository;
    @Autowired
    OrderMapper orderMapper;


    /**
    * GET  /litemallOrders : get the litemallOrders firstStringBaseColumn.
    */
    @Override
    public PageResult<LitemallOrder> findFirstStringColumn(String orderSn,Pageable pageable){
        String str = orderSn;
        if (Objects.nonNull(pageable)) {
            PageHelper.startPage(pageable.getPageNumber() + 1, pageable.getPageSize());
        }
        LitemallOrderExample litemallOrderExample = new LitemallOrderExample();
        String orderBy = getPageOrderBy(pageable);
        if(StringUtils.isNotEmpty(orderBy)) {
            litemallOrderExample.setOrderByClause(orderBy);
        }
        if (StringUtils.isEmpty(str)){
            litemallOrderExample.createCriteria();
        } else{
            litemallOrderExample.createCriteria().andOrderSnLike("%" + str +"%");
        }
        List<LitemallOrder>  data = litemallOrderRepository.selectByExample(litemallOrderExample);

        long count = 0L;
        if (CollectionUtils.isNotEmpty(data)){
            count = litemallOrderRepository.countByExample(litemallOrderExample);
        }
        return new PageResult<LitemallOrder>(data,count,count);
    }

    @Override
    public LitemallOrder findById(Integer userId, Integer orderId) {
        LitemallOrderExample example = new LitemallOrderExample();
        example.or().andIdEqualTo(orderId).andUserIdEqualTo(userId).andDeletedEqualTo(false);
        return litemallOrderRepository.selectOneByExample(example);
    }

    @Override
    public LitemallOrder findById(Integer orderId) {

            return litemallOrderRepository.selectByPrimaryKey(orderId);

    }

    @Override
    public void updateAftersaleStatus(Integer orderId, Short statusRequest) {
        LitemallOrder order = new LitemallOrder();
        order.setId(orderId);
        order.setAftersaleStatus(statusRequest);
        order.setUpdateTime(ZonedDateTime.now());
        litemallOrderRepository.updateByPrimaryKeySelective(order);
    }

    @Override
    public List<LitemallOrder> queryByOrderStatus(Integer userId, List<Short> orderStatus, Integer page, Integer limit, String sort, String order) {
        LitemallOrderExample example = new LitemallOrderExample();
        example.setOrderByClause(LitemallOrder.Column.addTime.desc());
        LitemallOrderExample.Criteria criteria = example.or();
        criteria.andUserIdEqualTo(userId);
        if (orderStatus != null) {
            criteria.andOrderStatusIn(orderStatus);
        }
        criteria.andDeletedEqualTo(false);
        if (!org.springframework.util.StringUtils.isEmpty(sort) && !org.springframework.util.StringUtils.isEmpty(order)) {
            example.setOrderByClause(sort + " " + order);
        }

        PageHelper.startPage(page, limit);
        return litemallOrderRepository.selectByExample(example);
    }

    @Override
    public String generateOrderSn(Integer userId) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMdd");
        String now = df.format(LocalDate.now());
        String orderSn = now + getRandomNum(6);
        while (countByOrderSn(userId, orderSn) != 0) {
            orderSn = now + getRandomNum(6);
        }
        return orderSn;
    }

    @Override
    public int add(LitemallOrder order) {
        order.setAddTime(ZonedDateTime.now());
        order.setUpdateTime(ZonedDateTime.now());
        return litemallOrderRepository.insertSelective(order);
    }

//    @Override
//    public List<LitemallOrder> queryUnpaid(Integer orderUnpaid) {
//        LitemallOrderExample example = new LitemallOrderExample();
//        example.or().andOrderStatusEqualTo(OrderUtil.STATUS_CREATE).andDeletedEqualTo(false);
//        return litemallOrderRepository.selectByExample(example);
//    }

    @Override
    public int updateWithOptimisticLocker(LitemallOrder order) {
        ZonedDateTime preUpdateTime = order.getUpdateTime();
        order.setUpdateTime(ZonedDateTime.now());
        return orderMapper.updateWithOptimisticLocker(preUpdateTime.toLocalDateTime(), order);
    }

    @Override
    public LitemallOrder findBySn(String orderSn) {
        LitemallOrderExample example = new LitemallOrderExample();
        example.or().andOrderSnEqualTo(orderSn).andDeletedEqualTo(false);
        return litemallOrderRepository.selectOneByExample(example);
    }

    @Override
    public void deleteById(Integer orderId) {
        litemallOrderRepository.logicalDeleteByPrimaryKey(orderId);
    }

    @Override
    public Map<Object, Object> orderInfo(Integer userId) {
        LitemallOrderExample example = new LitemallOrderExample();
        example.or().andUserIdEqualTo(userId).andDeletedEqualTo(false);
        List<LitemallOrder> orders = litemallOrderRepository.selectByExampleSelective(example, LitemallOrder.Column.orderStatus, LitemallOrder.Column.comments);

        int unpaid = 0;
        int unship = 0;
        int unrecv = 0;
        int uncomment = 0;
        for (LitemallOrder order : orders) {
            if (OrderUtil.isCreateStatus(order)) {
                unpaid++;
            } else if (OrderUtil.isPayStatus(order)) {
                unship++;
            } else if (OrderUtil.isShipStatus(order)) {
                unrecv++;
            } else if (OrderUtil.isConfirmStatus(order) || OrderUtil.isAutoConfirmStatus(order)) {
                uncomment += order.getComments();
            } else {
                // do nothing
            }
        }

        Map<Object, Object> orderInfo = new HashMap<Object, Object>();
        orderInfo.put("unpaid", unpaid);
        orderInfo.put("unship", unship);
        orderInfo.put("unrecv", unrecv);
        orderInfo.put("uncomment", uncomment);
        return orderInfo;
    }

    private int countByOrderSn(Integer userId, String orderSn) {
        LitemallOrderExample example = new LitemallOrderExample();
        example.or().andUserIdEqualTo(userId).andOrderSnEqualTo(orderSn).andDeletedEqualTo(false);
        return (int) litemallOrderRepository.countByExample(example);
    }

    private String getPageOrderBy(Pageable page) {
        if(page!= null && page.getSort() != null) {
            StringBuilder sb = new StringBuilder();
            page.getSort().forEach(sort -> sb.append(sort.getProperty())
            .append(" ").append(sort.getDirection()).append(","));
            if(sb.length() > 1) {
                return (sb.substring(0,sb.length()-1));
             }
        }
        return null;
    }
}
